import { App } from "../../application";
import Events from "../../application/constants/Events";
import { Polyline, Point } from "../../Docs";
import { InteractionEvent } from "../../processor/Mouse";

/**
 * 线编辑
 */
export default class EidtPolyline {
    private app: App;
    private polyline: Polyline;
    private clickListener;
    private rightClickListener;
    private moveListener;
    private isSameWithFrist = 'sameWithFrist';
    private isCricleLine: boolean; //是否绘制闭环的线
    private isOpen: boolean = false;

    /**
     * 线编辑
     * @example var lineData = { //线条的参数
            pointArray: null, //pointArray,  //多边形的顶点数组
            color: '#00FA9A',
            lineWidth: 5,  //线的宽度
            isCricleLine: false, //绘制的线是否是环形的
        };
        function clickListener(point){ //鼠标左键点击的监听器
           console.log(point);
        }

        function rightClickListener(point){ //鼠标右键点击的监听器
            console.log(point);
        }
        var eidtPolyline = new GE.EidtPolyline();
        eidtPolyline.openEdit(lineData, clickListener, rightClickListener); //开启线编辑
        //eidtPolyline.closeEdit(); //关闭线编辑
     */
    constructor() {
        this.app = App.getInstance();
    }

    /**
     * 打开线编辑功能
     * @param lineParam 线的属性
     * @param lineParam.color 线的颜色
     * @param lineParam.lineWidth 线的宽度
     * @param lineParam.isCricleLine 是否绘制闭环的线
     * @param lineParam.depthTest 是否开启深度检测, 可选参数，默认为false
     * @param lineParam.transparent 是否开启透明, 可选参数，默认为true
     * @param clickListener 鼠标左键点击的监听器, 该监听有一个参数: point。它是点击的点
     * @param rightClickListener 鼠标右键点击的监听器, 该监听有三个参数：point, pointArray, polyline。 point是点击的点, pointArray是当前多边形的顶点数组, polyline是当前线的对象
     * @example var lineData = { //线条的参数
            pointArray: null, //pointArray,  //多边形的顶点数组
            color: '#00FA9A',
            lineWidth: 5,  //线的宽度
            isCricleLine: false, //绘制的线是否是环形的
        };
        function clickListener(point){ //鼠标左键点击的监听器
           console.log(point);
        }

        function rightClickListener(point, pointArray, polyline){ //鼠标右键点击的监听器
            console.log(point);
        }
        eidtPolyline.openEdit(lineData, clickListener, rightClickListener);
     */
    public openEdit(lineParam: { color?: string, lineWidth?: number, isCricleLine?: boolean, depthTest?: boolean, transparent?: boolean;}, clickListener?, rightClickListener?, moveListener?) {
        if (this.isOpen) {
            return;
        }
        this.isCricleLine = (lineParam.isCricleLine == undefined) ? false : lineParam.isCricleLine;
        this.clickListener = clickListener;
        this.rightClickListener = rightClickListener;
        this.moveListener = moveListener;

        this.polyline = new Polyline(lineParam);
        this.polyline.renderOrder = Infinity;
        this.app.add(this.polyline);

        this.register();
        this.isOpen = true;
    }

    /**
     * 关闭线编辑功能
     * @example eidtPolyline.closeEdit();
     */
    public closeEdit() {
        this.app.remove(this.polyline);

        this.cancleEvent();

        this.isOpen = false;
    }

    /**
     * 获取线条对象
     * @returns 线条对象
     * @example eidtPolyline.getWire();
     */
    public getWire() {
        return this.polyline;
    }

    private register() {
        this.app.on(Events.Click, this.handleLeftClickEvent, this);
        this.app.on(Events.MouseMove, this.handleMoveEvent, this);
        this.app.on(Events.RightClick, this.handleRightClickEvent, this);

        this.app.mouse.addRaycasterType(Events.MouseMove);  //开启鼠标移动时的射线拾取功能
    }

    private cancleEvent() {
        this.app.off(Events.Click, this.handleLeftClickEvent, this);
        this.app.off(Events.MouseMove, this.handleMoveEvent, this);
        this.app.off(Events.RightClick, this.handleRightClickEvent, this);

        this.app.mouse.removeRaycasterType(Events.MouseMove);  //关闭鼠标移动时的射线拾取功能
    }

    private handleLeftClickEvent(data: InteractionEvent) {
        let pointArray = this.polyline.getPointArray();
        if (this.isCricleLine && pointArray.length >= 3) { //此时已经是闭环线，删掉最后一个点
            let lastPoint = pointArray[pointArray.length - 1];
            if (lastPoint[this.isSameWithFrist] == true) {
                this.polyline.removePoint(pointArray.length - 1);
            }
        }

        let clickPoint: Point = data.lnglat.clone();
        if (this.clickListener) {
            this.clickListener(clickPoint);
        }
        clickPoint.toEPSGWeb();

        if (pointArray.length > 1) {
            this.polyline.removePoint(pointArray.length - 1); //避免重复
        }

        this.polyline.addPoint(clickPoint.clone());
        this.polyline.addPoint(clickPoint.clone()); //多添加一个点，是为了在鼠标移动的时候操作这个多添加的点，并且在下一次鼠标点击的时候把这个点删除掉

        if (this.isCricleLine && pointArray.length >= 3) {//构成闭环线
            let firstPoint = pointArray[0].clone();
            firstPoint[this.isSameWithFrist] = true;
            //添加首元素
            this.polyline.addPoint(firstPoint);
        }
    }

    private handleRightClickEvent(data: InteractionEvent) {
        let clickPoint: Point = data.lnglat.clone();
        clickPoint.toEPSGWeb();

        let pointArray = this.polyline.getPointArray();
        if (pointArray.length < 1) {
            return;
        }

        if (this.isCricleLine && pointArray.length >= 3) {  //此时已经是闭环线，删掉倒数第二个点，因为倒数第二个点跟随鼠标
            let lastPoint = pointArray[pointArray.length - 1];
            if (lastPoint[this.isSameWithFrist] == true) {
                this.polyline.removePoint(pointArray.length - 2);
            }
        } else {  //不是闭环线，删掉倒数第一个点，因为倒数第一个点是跟随鼠标的点
            this.polyline.removePoint(pointArray.length - 1);
        }

        this.cancleEvent();

        if (this.rightClickListener) {
            this.rightClickListener(clickPoint, pointArray, this.polyline);
        }
    }

    private handleMoveEvent(data: InteractionEvent) {
        let pointArray = this.polyline.getPointArray();
        if (pointArray.length < 1) {
            return;
        }

        if (this.isCricleLine && pointArray.length >= 3) { //此时已经是闭环线，删掉最后一个点
            let lastPoint = pointArray[pointArray.length - 1];
            if (lastPoint[this.isSameWithFrist] == true) {
                this.polyline.removePoint(pointArray.length - 1);
            }
        }

        let clickPoint: Point = data.lnglat;
        if(this.moveListener){
            this.moveListener(clickPoint);
        }
        this.polyline.updatePoint(pointArray.length - 1, clickPoint);

        if (this.isCricleLine && pointArray.length >= 3) { //构成闭环线
            let firstPoint = pointArray[0].clone();
            firstPoint[this.isSameWithFrist] = true;
            //添加首元素
            this.polyline.addPoint(firstPoint);
        }
    }
}